#ifndef _client_h_
#define _client_h_

/*---------------Constant values ---------------*/

//server's Port
#define SERVER_PORT			61255

/* Default config filename */
#define DEFAULT_FILE "config.txt"
/* Log filename */
#define LOG_FILE "/tmp/NAT_LOG_FILE"

/* Response codes from server */
#define INVALID_ID                              1
#define SERVER_FULL                             2
#define NOT_REGISTERED                          3
#define REGISTER_OK                             4
#define REGISTER_NOT_OK                         5
#define UNREGISTER_OK                           6
#define UNREGISTER_NOT_OK                       7
#define CLIENT_FOUND                            8
#define CLIENT_NOT_FOUND                        9
#define INVALID_COMMAND                         10
#define GENERAL_ERROR                           11

/* Library status */
#define LIB_INITIAL_STATUS			    0x0000
#define LIB_IS_INITIALIZED			    1
#define LIB_TRAVERSAL_POSSIBLE			2


/* Known commands in UDP packets */
#define REGISTER		1
#define UNREGISTER		2
#define REQUEST_DATA	3

/* Traversal needed parameters */
#define NAT_TRAVERSAL_TIMEOUT       2
#define NAT_MAX_ATTEMPTS            10
#define NAT_MAGIC_NR                0x11660000
#define NAT_PUBLIC_FLAG             0x00004444
#define NAT_PRIVATE_FLAG            0x00002222

/*-----------End of Constant values -------------*/

/*----------------------Data types---------------*/
/* Structure to be sent to the server and to be read from packets*/
typedef struct PacketData {
        int myPort;//port
        int myIP;//ip
        int myID;//id
        int command;
        int cmdArgs;// cmdArgs
        int responseCode;
        int response[4];
} PacketData_t;

/* Structure containing communication data to be
used in NAT Traversal*/
typedef struct CommunicationData {
        int privatePort;
        int privateIP;
        int publicPort;
        int publicIP;
} CommunicationData_t;

typedef struct MyLibraryData {
	int libStatus;
	int localIP;
	int localPort;
	int clientID;
	int serverPort;
    int serverIP; //in network byte order
	//int localSocketFd;
	//timer pentru timeout;
	//CommunicationData_t *peerDetails;
} MyLibraryData_t;

/* Structure containing the EndPoints that it will be used 
to communicate after traversal was performed*/
typedef struct RealEndPoints {
        int IP;
        int Port;
} RealEndPoints_t;

/*------------------End of Data types-------------*/

/*------------------Functions --------------------*/

/* Returns 1 if the library was initialized. 0 is returned if not.*/
int libIsInitialized(MyLibraryData_t libData)
{
    if ( libData.libStatus&0x000f )
        return 1;
    return 0;
}

/* Returns 1 if the integer contains NAT_MAGIC_NR. 0 is returned if not.*/
int containsMagic(int number)
{
    if ( (number & 0xffff0000) == NAT_MAGIC_NR )
        return 1;
    return 0;
}

/* Returns 1 if the integer contains NAT_PUBLIC_FLAG. 0 is returned if not.*/
int isFromPublic(int number)
{
    if ( (number & 0x0000ffff) == NAT_PUBLIC_FLAG )
        return 1;
    return 0;
}

/* Returns 1 if the integer contains NAT_PRIVATE_FLAG. 0 is returned if not.*/
int isFromPrivate(int number)
{
    if ( (number & 0x0000ffff) == NAT_PRIVATE_FLAG )
        return 1;
    return 0;
}

/*
int NAT_initLibrary(int localPort, int clientID, int serverPort, int serverIP);

This function initialize the library with the parameters provided
Return values:
	 0 Initialization OK. All required parameters provided.
    -1 Initialization failed.
	-2 Library already initialized.
    -GENERAL_ERROR Any other error.
*/
int NAT_initLibrary(int, int, int, int);

/*
int NAT_register();
This function registers the client through the NAT Traversal server.
Return values:
	 0 Client registered succesfully.
	-1 Library not initialized.
	-SERVER_FULL Server exceeded the maximum client number.
	-INVALID_ID Invalid client ID.
    -GENERAL_ERROR Any other error.
*/
int NAT_register();

/*
int NAT_requestCommunicationData(int ClientID, CommunicationData_t *response);
This function requests communication parameters, required in NAT Traversal
algorithm, for a specified client.
If the return value is 0, the function fills up the CommunicationData_t structure, passed as a pointer to this function.
Return values:
	 0 Communication parameters successfully obtained.
	-GENERAL_ERROR from server.
	-CLIENT_NOT_FOUND client not found on the server.
*/
int NAT_requestCommunicationData(int , CommunicationData_t *);

/*
int NAT_tryTraversal(CommunicationData_t *destDetail, RealEndPoints_t *endPoints);
This function starts the UDP hole punching method across NAT.
After a successfull call of requestCommunicationData, the software must provide
to the library the destination details.
If it possible to punch through NAT, 
then the RealEndPoints_t *endPoints structure will be filled up with the peer client details.
Return values:
	 0 The traversal is possible, 
        the software can connect to the other client using endPoints.
	-1 The traversal is not possible.
    -GENERAL_ERROR Any other error. 
*/
int NAT_tryTraversal(CommunicationData_t *, RealEndPoints_t *);

/*
int NAT_sendDataToPeer(void *pointerToData, int count);
This function 
Return values:
	On succes it returns the number of bytes that was sent to the Peer.
	On failure it returns socket specific errors.
*/
int NAT_sendDataToPeer(void *, int);


/*
int NAT_unregister();
This function unregisters the client. After the client was unregistered through the server,
you must call again NAT_initLibrary();
Return values:
	0 Successfully unregistered.
	-INVALID_ID The client is not registered through the server.
	-UNREGISTER_NOT_OK The server cannot unregister client.
        -GENERAL_ERROR Any other error.
*/
int NAT_unregister();

/*
int waitForConnection();
This function opens a socket on local machine on the port the library was initialized to.
Then it waits for another client to send an integer containing a so called "magic nr".
This integer is transmitted by another client that tries to attempt a NAT traversal.
If the magic number is received the function sends back this integer and returns 0.
This function is a blocking function.
In case an error occurs, -1 it's returned.
*/
int waitForConnection();
/*---------------End of Functions -----------------*/

#endif
